{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "25P38JgWSYbZ"
   },
   "source": [
    "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/timsainb/tensorflow2-generative-models/blob/master/3.0-WGAN-GP-fashion-mnist.ipynb)\n",
    "\n",
    "## Wasserstein GAN with Gradient Penalty (WGAN-GP) ([article](https://arxiv.org/abs/1701.07875)) \n",
    "\n",
    "WGAN-GP is a GAN that improves over the original loss function to improve training stability. \n",
    "\n",
    "![wgan gp](https://github.com/timsainb/tensorflow2-generative-models/blob/f3360a819b5773692e943dfe181972a76b9d91bb/imgs/gan.png?raw=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "DoEPSlfmSYbc"
   },
   "source": [
    "### Install packages if in colab"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-05-14T06:31:29.973887Z",
     "start_time": "2019-05-14T06:31:29.969185Z"
    },
    "colab": {},
    "colab_type": "code",
    "id": "WbqrTgB_SYbf"
   },
   "outputs": [],
   "source": [
    "### install necessary packages if in colab\n",
    "def run_subprocess_command(cmd):\n",
    "  process = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)\n",
    "  for line in process.stdout:\n",
    "      print(line.decode().strip())\n",
    "      \n",
    "import sys, subprocess\n",
    "IN_COLAB = 'google.colab' in sys.modules\n",
    "colab_requirements = ['pip install tf-nightly-gpu-2.0-preview==2.0.0.dev20190513']\n",
    "if IN_COLAB:\n",
    "  for i in colab_requirements:\n",
    "    run_subprocess_command(i)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "3eKFKF5HSYbi"
   },
   "source": [
    "### load packages"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "UjL-sOZzSYbj"
   },
   "outputs": [],
   "source": [
    ""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-05-14T06:31:30.061880Z",
     "start_time": "2019-05-14T06:31:29.975587Z"
    },
    "colab": {},
    "colab_type": "code",
    "id": "at1xYevFSYbl",
    "outputId": "d70e29a0-b0d0-416b-b163-28974fab61fa"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "env: CUDA_VISIBLE_DEVICES=3\n"
     ]
    }
   ],
   "source": [
    "# make visible the only one GPU\n",
    "%env CUDA_VISIBLE_DEVICES=3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-05-14T06:31:33.702580Z",
     "start_time": "2019-05-14T06:31:30.063437Z"
    },
    "colab": {},
    "colab_type": "code",
    "id": "759gzUFlSYbq",
    "outputId": "d2ec559a-bbb8-4785-8e42-f355c270fbce"
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/mnt/cube/tsainbur/conda_envs/tpy3/lib/python3.6/site-packages/tqdm/autonotebook/__init__.py:14: TqdmExperimentalWarning: Using `tqdm.autonotebook.tqdm` in notebook mode. Use `tqdm.tqdm` instead to force console mode (e.g. in jupyter console)\n",
      "  \" (e.g. in jupyter console)\", TqdmExperimentalWarning)\n"
     ]
    }
   ],
   "source": [
    "import tensorflow as tf\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from tqdm.autonotebook import tqdm\n",
    "%matplotlib inline\n",
    "from IPython import display\n",
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-05-14T06:31:33.711214Z",
     "start_time": "2019-05-14T06:31:33.706313Z"
    },
    "colab": {},
    "colab_type": "code",
    "id": "AxY3I4SfSYbt",
    "outputId": "64769acf-bcf3-4ab4-d753-a69ec24b2ee5"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2.0.0-dev20190513\n"
     ]
    }
   ],
   "source": [
    "print(tf.__version__)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "LdCkp6ybSYbw"
   },
   "source": [
    "### Create a fashion-MNIST dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-05-14T06:31:33.803523Z",
     "start_time": "2019-05-14T06:31:33.714599Z"
    },
    "colab": {},
    "colab_type": "code",
    "id": "Ypym6ZAESYbx"
   },
   "outputs": [],
   "source": [
    "TRAIN_BUF=60000\n",
    "BATCH_SIZE=512\n",
    "TEST_BUF=10000\n",
    "DIMS = (28,28,1)\n",
    "N_TRAIN_BATCHES =int(TRAIN_BUF/BATCH_SIZE)\n",
    "N_TEST_BATCHES = int(TEST_BUF/BATCH_SIZE)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-05-14T06:31:38.044471Z",
     "start_time": "2019-05-14T06:31:33.805821Z"
    },
    "colab": {},
    "colab_type": "code",
    "id": "xhqU6sqiSYbz"
   },
   "outputs": [],
   "source": [
    "# load dataset\n",
    "(train_images, _), (test_images, _) = tf.keras.datasets.fashion_mnist.load_data()\n",
    "\n",
    "# split dataset\n",
    "train_images = train_images.reshape(train_images.shape[0], 28, 28, 1).astype(\n",
    "    \"float32\"\n",
    ") / 255.0\n",
    "test_images = test_images.reshape(test_images.shape[0], 28, 28, 1).astype(\"float32\") / 255.0\n",
    "\n",
    "# batch datasets\n",
    "train_dataset = (\n",
    "    tf.data.Dataset.from_tensor_slices(train_images)\n",
    "    .shuffle(TRAIN_BUF)\n",
    "    .batch(BATCH_SIZE)\n",
    ")\n",
    "test_dataset = (\n",
    "    tf.data.Dataset.from_tensor_slices(test_images)\n",
    "    .shuffle(TEST_BUF)\n",
    "    .batch(BATCH_SIZE)\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "HLxPlL7QSYb1"
   },
   "source": [
    "### Define the network as tf.keras.model object"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-05-14T06:31:38.068468Z",
     "start_time": "2019-05-14T06:31:38.046751Z"
    },
    "colab": {},
    "colab_type": "code",
    "id": "Wyipg-4oSYb1"
   },
   "outputs": [],
   "source": [
    "class WGAN(tf.keras.Model):\n",
    "    \"\"\"[summary]\n",
    "    I used github/LynnHo/DCGAN-LSGAN-WGAN-GP-DRAGAN-Tensorflow-2/ as a reference on this.\n",
    "    \n",
    "    Extends:\n",
    "        tf.keras.Model\n",
    "    \"\"\"\n",
    "\n",
    "    def __init__(self, **kwargs):\n",
    "        super(WGAN, self).__init__()\n",
    "        self.__dict__.update(kwargs)\n",
    "\n",
    "        self.gen = tf.keras.Sequential(self.gen)\n",
    "        self.disc = tf.keras.Sequential(self.disc)\n",
    "\n",
    "    def generate(self, z):\n",
    "        return self.gen(z)\n",
    "\n",
    "    def discriminate(self, x):\n",
    "        return self.disc(x)\n",
    "\n",
    "    def compute_loss(self, x):\n",
    "        \"\"\" passes through the network and computes loss\n",
    "        \"\"\"\n",
    "        ### pass through network\n",
    "        # generating noise from a uniform distribution\n",
    "\n",
    "        z_samp = tf.random.normal([x.shape[0], 1, 1, self.n_Z])\n",
    "\n",
    "        # run noise through generator\n",
    "        x_gen = self.generate(z_samp)\n",
    "        # discriminate x and x_gen\n",
    "        logits_x = self.discriminate(x)\n",
    "        logits_x_gen = self.discriminate(x_gen)\n",
    "\n",
    "        # gradient penalty\n",
    "        d_regularizer = self.gradient_penalty(x, x_gen)\n",
    "        ### losses\n",
    "        disc_loss = (\n",
    "            tf.reduce_mean(logits_x)\n",
    "            - tf.reduce_mean(logits_x_gen)\n",
    "            + d_regularizer * self.gradient_penalty_weight\n",
    "        )\n",
    "\n",
    "        # losses of fake with label \"1\"\n",
    "        gen_loss = tf.reduce_mean(logits_x_gen)\n",
    "\n",
    "        return disc_loss, gen_loss\n",
    "\n",
    "    def compute_gradients(self, x):\n",
    "        \"\"\" passes through the network and computes loss\n",
    "        \"\"\"\n",
    "        ### pass through network\n",
    "        with tf.GradientTape() as gen_tape, tf.GradientTape() as disc_tape:\n",
    "            disc_loss, gen_loss = self.compute_loss(x)\n",
    "\n",
    "        # compute gradients\n",
    "        gen_gradients = gen_tape.gradient(gen_loss, self.gen.trainable_variables)\n",
    "\n",
    "        disc_gradients = disc_tape.gradient(disc_loss, self.disc.trainable_variables)\n",
    "\n",
    "        return gen_gradients, disc_gradients\n",
    "\n",
    "    def apply_gradients(self, gen_gradients, disc_gradients):\n",
    "\n",
    "        self.gen_optimizer.apply_gradients(\n",
    "            zip(gen_gradients, self.gen.trainable_variables)\n",
    "        )\n",
    "        self.disc_optimizer.apply_gradients(\n",
    "            zip(disc_gradients, self.disc.trainable_variables)\n",
    "        )\n",
    "\n",
    "    def gradient_penalty(self, x, x_gen):\n",
    "        epsilon = tf.random.uniform([x.shape[0], 1, 1, 1], 0.0, 1.0)\n",
    "        x_hat = epsilon * x + (1 - epsilon) * x_gen\n",
    "        with tf.GradientTape() as t:\n",
    "            t.watch(x_hat)\n",
    "            d_hat = self.discriminate(x_hat)\n",
    "        gradients = t.gradient(d_hat, x_hat)\n",
    "        ddx = tf.sqrt(tf.reduce_sum(gradients ** 2, axis=[1, 2]))\n",
    "        d_regularizer = tf.reduce_mean((ddx - 1.0) ** 2)\n",
    "        return d_regularizer\n",
    "\n",
    "    @tf.function\n",
    "    def train(self, train_x):\n",
    "        gen_gradients, disc_gradients = self.compute_gradients(train_x)\n",
    "        self.apply_gradients(gen_gradients, disc_gradients)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "qEVl58nDSYb4"
   },
   "source": [
    "### Define the network architecture"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-05-14T06:31:38.219862Z",
     "start_time": "2019-05-14T06:31:38.070570Z"
    },
    "colab": {},
    "colab_type": "code",
    "id": "dyU21SGbSYb4"
   },
   "outputs": [],
   "source": [
    "N_Z = 64\n",
    "\n",
    "generator = [\n",
    "    tf.keras.layers.Dense(units=7 * 7 * 64, activation=\"relu\"),\n",
    "    tf.keras.layers.Reshape(target_shape=(7, 7, 64)),\n",
    "    tf.keras.layers.Conv2DTranspose(\n",
    "        filters=64, kernel_size=3, strides=(2, 2), padding=\"SAME\", activation=\"relu\"\n",
    "    ),\n",
    "    tf.keras.layers.Conv2DTranspose(\n",
    "        filters=32, kernel_size=3, strides=(2, 2), padding=\"SAME\", activation=\"relu\"\n",
    "    ),\n",
    "    tf.keras.layers.Conv2DTranspose(\n",
    "        filters=1, kernel_size=3, strides=(1, 1), padding=\"SAME\", activation=\"sigmoid\"\n",
    "    ),\n",
    "]\n",
    "\n",
    "discriminator = [\n",
    "    tf.keras.layers.InputLayer(input_shape=DIMS),\n",
    "    tf.keras.layers.Conv2D(\n",
    "        filters=32, kernel_size=3, strides=(2, 2), activation=\"relu\"\n",
    "    ),\n",
    "    tf.keras.layers.Conv2D(\n",
    "        filters=64, kernel_size=3, strides=(2, 2), activation=\"relu\"\n",
    "    ),\n",
    "    tf.keras.layers.Flatten(),\n",
    "    tf.keras.layers.Dense(units=1, activation=\"sigmoid\"),\n",
    "]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-05-10T18:40:40.306731Z",
     "start_time": "2019-05-10T18:40:40.292930Z"
    },
    "colab_type": "text",
    "id": "wi_ZuWBdSYb6"
   },
   "source": [
    "### Create Model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-05-14T06:31:39.047233Z",
     "start_time": "2019-05-14T06:31:38.222179Z"
    },
    "colab": {},
    "colab_type": "code",
    "id": "dSYjNRAwSYb7"
   },
   "outputs": [],
   "source": [
    "# optimizers\n",
    "gen_optimizer = tf.keras.optimizers.Adam(0.0001, beta_1=0.5)\n",
    "disc_optimizer = tf.keras.optimizers.RMSprop(0.0005)# train the model\n",
    "# model\n",
    "model = WGAN(\n",
    "    gen = generator,\n",
    "    disc = discriminator,\n",
    "    gen_optimizer = gen_optimizer,\n",
    "    disc_optimizer = disc_optimizer,\n",
    "    n_Z = N_Z,\n",
    "    gradient_penalty_weight = 10.0\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "qwBg8NwrSYb9"
   },
   "source": [
    "### Train the model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-05-14T06:31:39.056490Z",
     "start_time": "2019-05-14T06:31:39.049635Z"
    },
    "colab": {},
    "colab_type": "code",
    "id": "47sz8RMeSYb-"
   },
   "outputs": [],
   "source": [
    "# exampled data for plotting results\n",
    "def plot_reconstruction(model, nex=8, zm=2):\n",
    "    samples = model.generate(tf.random.normal(shape=(BATCH_SIZE, N_Z)))\n",
    "    fig, axs = plt.subplots(ncols=nex, nrows=1, figsize=(zm * nex, zm))\n",
    "    for axi in range(nex):\n",
    "        axs[axi].matshow(\n",
    "                    samples.numpy()[axi].squeeze(), cmap=plt.cm.Greys, vmin=0, vmax=1\n",
    "                )\n",
    "        axs[axi].axis('off')\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-05-14T06:31:39.152670Z",
     "start_time": "2019-05-14T06:31:39.058505Z"
    },
    "colab": {},
    "colab_type": "code",
    "id": "pKkEX9yBSYcB"
   },
   "outputs": [],
   "source": [
    "# a pandas dataframe to save the loss information to\n",
    "losses = pd.DataFrame(columns = ['disc_loss', 'gen_loss'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-05-14T07:04:26.791634Z",
     "start_time": "2019-05-14T07:04:17.126436Z"
    },
    "colab": {},
    "colab_type": "code",
    "id": "00dI2M4iSYcE",
    "outputId": "8312d004-9e5d-43a1-f28f-6d182bd9add2"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch: 0 | disc_loss: -0.050283897668123245 | gen_loss: 0.5204998254776001\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 1152x144 with 8 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light",
      "tags": []
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "n_epochs = 200\n",
    "for epoch in range(n_epochs):\n",
    "    # train\n",
    "    for batch, train_x in tqdm(\n",
    "        zip(range(N_TRAIN_BATCHES), train_dataset), total=N_TRAIN_BATCHES\n",
    "    ):\n",
    "        model.train(train_x)\n",
    "    # test on holdout\n",
    "    loss = []\n",
    "    for batch, test_x in tqdm(\n",
    "        zip(range(N_TEST_BATCHES), test_dataset), total=N_TEST_BATCHES\n",
    "    ):\n",
    "        loss.append(model.compute_loss(train_x))\n",
    "    losses.loc[len(losses)] = np.mean(loss, axis=0)\n",
    "    # plot results\n",
    "    display.clear_output()\n",
    "    print(\n",
    "        \"Epoch: {} | disc_loss: {} | gen_loss: {}\".format(\n",
    "            epoch, losses.disc_loss.values[-1], losses.gen_loss.values[-1]\n",
    "        )\n",
    "    )\n",
    "    plot_reconstruction(model)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-05-14T06:46:24.425722Z",
     "start_time": "2019-05-14T06:46:24.188266Z"
    },
    "colab": {},
    "colab_type": "code",
    "id": "XZbwB70ESYcH",
    "outputId": "40913f5e-a991-4d25-c56a-086acb4c0cd6"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x7f82bc2fe668>]"
      ]
     },
     "execution_count": 15,
     "metadata": {
      "tags": []
     },
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light",
      "tags": []
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(losses.gen_loss.values)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-05-14T06:46:38.649136Z",
     "start_time": "2019-05-14T06:46:38.440378Z"
    },
    "colab": {},
    "colab_type": "code",
    "id": "FydTnKDxSYcL",
    "outputId": "503e0a49-2ed1-4c2d-9072-adc57dae5ae8"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x7f8298127278>]"
      ]
     },
     "execution_count": 17,
     "metadata": {
      "tags": []
     },
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light",
      "tags": []
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(losses.disc_loss.values)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 0,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "R4EjPZD1SYcO"
   },
   "outputs": [],
   "source": [
    ""
   ]
  }
 ],
 "metadata": {
  "accelerator": "GPU",
  "colab": {
   "collapsed_sections": [],
   "name": "3.0-WGAN-GP-fashion-mnist.ipynb",
   "provenance": [],
   "toc_visible": true,
   "version": "0.3.2"
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
